package com.hzsparrow.ai.controller;

import java.util.UUID;
import java.util.concurrent.CompletableFuture;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.hzsparrow.ai.entity.ChatHistory;
import com.hzsparrow.ai.entity.Conversation;
import com.hzsparrow.ai.entity.KnowledgeBase;
import com.hzsparrow.ai.entity.User;
import com.hzsparrow.ai.service.ChatHistoryService;
import com.hzsparrow.ai.service.ChatService;
import com.hzsparrow.ai.service.ConversationService;
import com.hzsparrow.ai.service.DocumentService;
import com.hzsparrow.ai.service.KnowledgeBaseService;
import com.hzsparrow.ai.service.UserService;

import reactor.core.publisher.Flux;

@RestController
public class ChatController {

    private final ChatService chatService;
    private final DocumentService documentService;
    private final ChatHistoryService chatHistoryService;
    private final KnowledgeBaseService knowledgeBaseService;
    private final UserService userService;
    private final ConversationService conversationService;

    @Autowired
    public ChatController(
            ChatService chatService,
            DocumentService documentService,
            ChatHistoryService chatHistoryService,
            KnowledgeBaseService knowledgeBaseService,
            UserService userService,
            ConversationService conversationService) {
        this.chatService = chatService;
        this.documentService = documentService;
        this.chatHistoryService = chatHistoryService;
        this.knowledgeBaseService = knowledgeBaseService;
        this.userService = userService;
        this.conversationService = conversationService;
    }

    @GetMapping("/api/chat")
    public Flux<String> chat(
            @RequestParam String message,
            @RequestParam(required = false) Long knowledgeBaseId,
            @RequestParam(required = false) String sessionId) {

        // 获取当前用户（如果已认证）
        User currentUser = null;
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated() &&
                    !authentication.getName().equals("anonymousUser")) {
                currentUser = userService.getUserByUsername(authentication.getName());
            }
        } catch (Exception e) {
            // 未认证用户，忽略错误继续处理
        }

        // 保存变量的最终引用，以便在lambda中使用
        final User finalCurrentUser = currentUser;

        // 创建或获取会话ID
        final String finalSessionId = (sessionId == null || sessionId.isEmpty())
                ? UUID.randomUUID().toString()
                : sessionId;

        // 检查知识库是否存在
        KnowledgeBase knowledgeBase = null;
        if (knowledgeBaseId != null) {
            knowledgeBase = knowledgeBaseService.getKnowledgeBase(knowledgeBaseId);
        }

        // 保存变量的最终引用，以便在lambda中使用
        final KnowledgeBase finalKnowledgeBase = knowledgeBase;
        final Long finalKnowledgeBaseId = knowledgeBaseId;

        // 获取向量索引名称，如果指定了知识库
        String vectorIndexName = finalKnowledgeBase != null ? finalKnowledgeBase.getVectorIndexName() : null;

        // 检查或创建Conversation对象
        if (finalCurrentUser != null) {
            // 检查是否存在此会话ID的对话
            Conversation existingConversation = conversationService.getConversationBySessionId(finalSessionId);

            if (existingConversation == null) {
                // 创建新的对话记录
                Conversation newConversation = new Conversation();
                newConversation.setSessionId(finalSessionId);
                newConversation.setUserId(finalCurrentUser.getId());
                newConversation.setKnowledgeBaseId(finalKnowledgeBaseId);

                // 使用消息内容的前30个字符作为对话标题
                String title = message.length() > 30 ? message.substring(0, 30) : message;
                newConversation.setTitle(title);

                conversationService.createConversation(newConversation);
            } else {
                // 如果标题为"新对话"，则用第一条消息内容更新标题
                if ("新对话".equals(existingConversation.getTitle())) {
                    String title = message.length() > 30 ? message.substring(0, 30) : message;
                    conversationService.updateConversationTitle(finalSessionId, title);
                } else {
                    // 更新对话的最后修改时间
                    conversationService.updateConversation(existingConversation);
                }
            }
        }

        // 处理聊天请求，同时记录对话历史
        Flux<String> response = chatService.processChat(message, vectorIndexName);

        // 转换为字符串以保存对话历史
        StringBuilder responseBuilder = new StringBuilder();

        return response
                .doOnNext(chunk -> {
                    // 收集响应内容
                    responseBuilder.append(chunk);
                })
                .doOnComplete(() -> {
                    String responseText = responseBuilder.toString();
                    saveHistoryAsync(finalCurrentUser, finalSessionId, finalKnowledgeBaseId,
                            message, responseText, finalKnowledgeBase != null);
                });
    }

    private void saveHistoryAsync(User user, String sessionId, Long knowledgeBaseId,
            String message, String response, boolean usedKnowledgeBase) {
        // 使用异步但非反应式的方式保存历史
        CompletableFuture.runAsync(() -> {
            try {
                if (user != null) {
                    ChatHistory history = new ChatHistory();
                    history.setSessionId(sessionId);
                    history.setUserId(user.getId());
                    history.setKnowledgeBaseId(knowledgeBaseId);
                    history.setUserMessage(message);
                    history.setAiResponse(response);
                    history.setUsedKnowledgeBase(usedKnowledgeBase);
                    chatHistoryService.save(history); // 使用基础的MyBatis-Plus保存方法
                }
            } catch (Exception e) {
                System.err.println("异步保存聊天历史失败: " + e.getMessage());
            }
        });
    }

    // 保留原来的GET方法以保持向后兼容
    @GetMapping("/api/addDocument")
    public String addDocument(@RequestParam String content) {
        return documentService.addDocument(content, null, "未命名文档");
    }

    // POST方法用于添加文档
    @PostMapping("/api/addDocument")
    public String addDocumentPost(@RequestBody DocumentRequest request) {
        return documentService.addDocument(request.getContent(), null, "未命名文档");
    }

    // 内部类，用于接收POST请求的JSON数据
    public static class DocumentRequest {
        private String content;

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }
}